feat(gui): add a Settings → Assets tab (refresh, clear cache, auto-download, open folder)#142
Conversation
Greptile SummaryThis PR adds a Settings → Assets tab with four controls: a toggle to gate automatic device-image downloads, a Refresh button (force-fetches for connected devices, bypassing the
Confidence Score: 5/5Safe to merge; the core sync deferral and cache-wipe logic is well-reasoned and the previously flagged race conditions are addressed. The deferred_manual queue correctly prevents cache wipes from racing in-flight syncs, the auto_download gate is read fresh on each inventory snapshot, and the back-compat serde default is in place. Two non-blocking quality issues remain: the Cache location button creates the cache dir but never opens a file manager on Linux, and a clear_cache() filesystem failure still resets in-memory bookkeeping — both cause wasteful behavior in edge cases but not data loss or incorrect state for typical users. crates/openlogi-gui/src/asset/mod.rs (reveal_cache_in_file_manager non-macOS path) and crates/openlogi-gui/src/main.rs (clear_cache error handling before state reset) Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as Settings Assets UI
participant Ctrl as AssetControl channel
participant Main as Main Event Loop
participant FS as Filesystem
participant Net as assets.openlogi.org
UI->>Ctrl: send Refresh
Ctrl->>Main: asset_ctrl_rx.recv()
alt sync_running is true
Main->>Main: "deferred_manual = Some(Refresh)"
Note over Main: waits for sync outcome
Main->>Ctrl: re-send deferred via asset_ctrl_self_tx
else sync_running is false
Main->>Main: "sync_running = true"
Main->>Net: spawn thread, run_asset_sync(latest_inv)
Net-->>Main: SyncOutcome ok, keys
Main->>Main: "sync_running = false, synced_keys union keys"
end
UI->>Ctrl: send ClearCache
Ctrl->>Main: asset_ctrl_rx.recv()
alt sync_running is true
Main->>Main: "deferred_manual = Some(ClearCache), beats Refresh"
else sync_running is false
Main->>FS: clear_cache, remove_dir_all
Main->>Main: "synced_keys.clear, index_refreshed=false, cache=new"
Main->>UI: cx.refresh_windows
Main->>Net: spawn thread, run_asset_sync(latest_inv)
end
UI->>UI: toggle auto_download ON
UI->>Ctrl: send Refresh immediately
Reviews (6): Last reviewed commit: "fix(gui): defer manual asset sync while ..." | Re-trigger Greptile |
1f833c8 to
79e2938
Compare
A persisted on/off preference (default on, backward-compatible via serde default) for whether the GUI fetches device images from the network when a device connects. Consumed by the runtime sync and the upcoming Settings → Assets tab; off keeps the app fully offline.
79e2938 to
2f24bd9
Compare
A new Assets page in Settings with four controls: - Automatically download device images — a toggle gating the startup sync on the new auto_download_assets setting; off makes the app issue no asset network requests (bundled art + silhouette still render). - Refresh assets — force-fetches images for the connected devices now, bypassing the should_run policy (so a release build with bundled art can still pull updated renders between releases). - Clear cache — shows the on-disk cache size and wipes the per-user cache, then re-fetches. - Cache location — reveals the downloaded-images folder in Finder. Manual actions reach the sync (which lives on the main event loop) via a new AssetControl global channel, mirroring PairingControl. The loop keeps the latest inventory so a manual refresh syncs the current devices immediately and resets the retry backoff. Asset cache helpers (cache_size_bytes / clear_cache / reveal_cache_in_file_manager) and a `force` flag on the sync entrypoint back the buttons. Strings translated for ja/ru/zh-CN/zh-HK/zh-TW (ja/ru best-effort, English-key fallback).
- Compute the asset-cache size once when the Settings window opens and store it on the view, instead of re-walking the cache dir on the main thread every render. (Greptile) - Extract the macOS Finder reveal into a cfg-gated helper so the early return isn't the function's last statement on non-macOS — CI clippy flagged needless_return on the Linux build (local macOS clippy can't see that path). The original commit also skipped the manual sync on an empty inventory to keep the old SYNC_DONE latch from wedging the auto-sync gate; the rebased loop has no such latch (it re-arms per model set, #220) and an index-only refresh is first-class there (#218), so that guard is dropped.
A manual Refresh / Clear that arrives while a background sync is running is stashed in `deferred_manual` instead of acting immediately, and the sync-outcome arm re-issues it (through the existing control channel) the moment that sync finishes. So a Clear never wipes the cache out from under the in-flight fetch's writes, and a second writer is never spawned alongside it. A queued Clear is not downgraded by a later Refresh.
2f24bd9 to
1237091
Compare
What
Adds a Settings → Assets tab to manage device-image assets, with four controls:
auto_download_assetssetting (default on). Off = the app makes no asset network requests at all; bundled art and the synthetic silhouette still render.should_runpolicy — so a release build that ships bundled art (and otherwise never syncs at runtime) can still pull updated renders between releases.How it's wired
The asset sync lives on the main event loop (the
AtomicU8state machine from #140). Manual actions reach it through a newAssetControlglobal channel — the same pattern asPairingControlfor the Add-Device window. The loop now:auto_download_assetssetting (read fromAppStateper snapshot);asset_ctrl_rxarm:ClearCachewipes the cache then both commands force a fresh fetch (sync_assets(.., force = true)skipsshould_run).New asset-module helpers back the buttons:
cache_size_bytes,clear_cache,reveal_cache_in_file_manager.Design notes
should_runreturns false), so fixes that only update the liveindex.json(e.g. fix(assets): match devices against every model id a depot lists #137'smodelIds) wouldn't reach those users without a Refresh. Refresh forces the fetch; the toggle, when on, doesn't change the existing release-bundle behavior (auto-sync stays gated byshould_run).auto_download_assetsis#[serde(default = "default_true")], so existing config files keep the current (auto-download) behavior;schema_versionis unchanged.i18n
New strings are translated for ja / ru / zh-CN / zh-HK / zh-TW (English msgid doubles as the key, so missing locales fall back to English). ja and ru are best-effort — corrections welcome.
Test plan
cargo test(core + gui, incl. the i18napp.ymlload),clippy -D warnings,fmtall green.Follow-up to #137 / #140.